package org.dstart.air.sql
{
	import flash.data.SQLConnection;
	import flash.data.SQLResult;
	import flash.data.SQLStatement;
	import flash.events.EventDispatcher;
	import flash.events.SQLErrorEvent;
	import flash.events.SQLEvent;
	import flash.events.TimerEvent;
	import flash.filesystem.File;
	import flash.utils.Timer;
	
	import org.dstart.air.sql.event.ESQLEvent;
	import org.dstart.air.sql.struct.SQLData;
	import org.dstart.object.debug.FDebug;

	public class SQLManage extends EventDispatcher
	{
		private var m_sqlConn:SQLConnection;		//	数据库连接对象
		private var m_sqlStream:SQLStatement;		//	数据库操作流
		
		private var sqlArray:Array;		//	要查询的 SQL 对象数组
		private var isCanRead:Boolean;	//	是否可以读取下一条 SQL 语句并处理
		
		private var gTime:Timer;		//	全局计时器
		private var nowSQLID:Number;	//	当前要处理的 SQL ID	 
		
		public function SQLManage()
		{	
			sqlArray = new Array();
		}
		
		//	连接到本地数据库
		public function ConnDataBase(sqlFile:File):void
		{
			if(!m_sqlConn)
			{
				try
				{
					m_sqlConn = new SQLConnection();
					SetConnListener(true);
					m_sqlConn.openAsync(sqlFile);
				}
				catch(e:*)
				{
					FDebug.showError("连接数据库出错,原因是:" +  e);
				}
			}
		}		
		
		//	加入一条 SQL 语句
		public function push(sql:String):void
		{
			if(!sqlArray)
			{
				sqlArray = new Array();
			}
			sqlArray.push(new SQLData(sql));
			FDebug.showInfo("当前压入SQL语句为:" + sqlArray.length);
		}
		
		//	关闭数据库
		public function Close():void
		{
			if(m_sqlConn.connected)
			{
				m_sqlConn.close();
				SetConnListener(false);
			}
		}
		
		//	取得数据库内表对象数组
		private function get tables():Array
		{
			try
			{
				if(m_sqlConn.connected)
				{
					return m_sqlConn.getSchemaResult().tables;
				}
			}
			catch(e:*)
			{
				FDebug.showError("当前数据库连接状态为:" + this.m_sqlConn);
				FDebug.showError("读取信息为:" + this.m_sqlConn.getSchemaResult());
			}
			return null;
		}
		
		//*****************************************************************//
		
		//	设置/取消 连接事件侦听
		private function SetConnListener(flag:Boolean):void
		{
			if(flag)
			{
				m_sqlConn.addEventListener(SQLEvent.OPEN, onConnDone);
				m_sqlConn.addEventListener(SQLErrorEvent.ERROR, onConnError);
				m_sqlConn.addEventListener(SQLEvent.SCHEMA, onSchema);
			}
			else
			{
				m_sqlConn.removeEventListener(SQLEvent.COMMIT, onConnDone);
				m_sqlConn.removeEventListener(SQLErrorEvent.ERROR, onConnError);
				m_sqlConn.removeEventListener(SQLEvent.SCHEMA, onSchema);
				m_sqlConn = null;
				
				FDebug.showError("数据库被关闭");
			}			
		}
		
		private function onSchema(e:SQLEvent):void
		{
			var esql:ESQLEvent = new ESQLEvent(ESQLEvent.GET_TABLES);
			esql.data = this.m_sqlConn.getSchemaResult().tables;
			
			this.dispatchEvent(esql);
			
			/**
			var se:SQLSchemaResult = this.m_sqlConn.getSchemaResult();
			var ts:SQLTableSchema = se.tables[0];
			var tArray:Array = se.tables[0].columns;
			
			FDebug.showError("Schema:" + e);
			FDebug.showError("now rush::" + se);
			FDebug.showError("now tables:;" + ts.name);
			
			for(var i:int = 0; i < tArray.length; i++)
			{
				var ta:SQLColumnSchema = tArray[i];
				FDebug.showError("talbes::  " + ta.dataType, ta.name, ta.defaultCollationType);
			}
			//**/
		}
		
		//	数据库连接成功
		private function onConnDone(e:SQLEvent):void
		{
			try
			{
				// SetConnListener(false);
				
				this.dispatchEvent(new ESQLEvent(ESQLEvent.CONN_DONE));
				
				m_sqlConn.loadSchema();
				
				//	设置一些状态标识为初始状态
				isCanRead = true;
				nowSQLID = 0;
				
				//	连接到数据库
				m_sqlStream = new SQLStatement();
				m_sqlStream.sqlConnection = m_sqlConn;
				m_sqlStream.addEventListener(SQLEvent.RESULT, onRushDataDone);
				m_sqlStream.addEventListener(SQLErrorEvent.ERROR, onRushDataError);
				
				//	开始扫描传入的 SQL 语句,并进行处理
				// isCanRead = true;
				gTime = new Timer(1);
				gTime.addEventListener(TimerEvent.TIMER, onCheckSQLString);
				gTime.start();
			}
			catch(e:*)
			{
				FDebug.showError("连接文件成功,但连接数据库时出错:" + e);
			}
		}
		
		//	数据库连接失败
		private function onConnError(e:SQLErrorEvent):void
		{
			SetConnListener(false);
			
			this.dispatchEvent(new ESQLEvent(ESQLEvent.CONN_ERROR));
		}

		//	检测 SQL 语句并处理
		private function onCheckSQLString(e:TimerEvent):void
		{
			if(m_sqlStream)
			{				
				if(isCanRead && sqlArray.length > 0)
				{
					FDebug.showInfo("开始执行 SQL 语句" + nowSQLID);
					// if(nowSQLID < sqlArray.length);
					if(sqlArray.length > 0)
					{
						try
						{
							var sd:SQLData = sqlArray.shift();//[nowSQLID];
							
							isCanRead = false;							
							
							FDebug.showInfo("当前要执行的SQL语句是:" + sd.sql);
							// FDebug.showInfo("当前检查的数据库是:" + this.m_sqlStream.sqlConnection);
							// FDebug.showInfo("当前数据库连接状态::" + this.m_sqlConn);
							
							this.m_sqlStream.text = sd.sql;
							this.m_sqlStream.execute();
						}
						catch(e:*)
						{							
							FDebug.showError("检测 SQL 语旬时出错:" +  e);
						}						
					}					 
				}
			}
		}

		//	数据库操作 SQL 语句成功
		private function onRushDataDone(e:SQLEvent):void
		{
			try
			{				
				var r:SQLResult = SQLStatement(e.currentTarget).getResult();

				var esql:ESQLEvent = new ESQLEvent(ESQLEvent.DATA_DONE);
				esql.data = r.data;
				
				this.dispatchEvent(esql);				
				this.isCanRead = true;
				this.nowSQLID ++;
			}
			catch(e:*)
			{				
				FDebug.showError("解释数据返回数据时出错:" +  e);
			}			
		}
		
		//	数据库操作 SQL 语句失败
		private function onRushDataError(e:SQLErrorEvent):void
		{
			try
			{
				this.isCanRead = true;
				this.nowSQLID ++;
				this.dispatchEvent(new ESQLEvent(ESQLEvent.DATA_ERROR));
			}
			catch(e:*)
			{				
				FDebug.showError("数据解析出错" +  e);
			}
		}
	}
}